<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="shortcut icon" href="./img/icon.png" type="image/x-icon">
  <title>Document</title>
  <script src="../vue.min.js"></script>
  <link rel="stylesheet" href="./index.css">
</head>
<body>
  <div id="app">
    <div class="layout">
      <div class="map">
        <!-- 渲染地图 -->
        <div v-for="(item1, index1) in mapList" :key="index1" class="map-tr">
          <div v-for="(item2, index2) in item1" :key="index2" class="map-td" :style="{ 'width': cell + 'px', 'height': cell + 'px' }"></div>
        </div>
        <!-- 渲染所有猪 -->
        <div
          v-for="(pig, index) in pigList"
          v-show="pig.show"
          :key="index"
          class="pig"
          :style="{
            width: pig.dir === 'top' || pig.dir === 'bottom' ? `${cell}px` : `${cell * 2}px`,
            height: pig.dir === 'top' || pig.dir === 'bottom' ? `${cell * 2}px` : `${cell}px`,
            left: pig.x + 'px',
            top: pig.y + 'px',
            backgroundImage: `url(./img/pig-${pig.dir}.png)`
          }"
          @click="clickPig(pig)"
        ></div>
      </div>
    </div>
  </div>
  
  <script>
    new Vue({
      el: '#app',
      data() {
        return {
          mapList: [], // 地图
          row: 9, // 行
          col: 9, // 列
          cell: 30, // 单元格的长宽
          speed: 5, // 猪的速度
          /**
           * 
           * 猪信息配置
           * 
           * dir:       猪头朝向  top、bottom、left、right
           * position:  猪头的坐标
           * x:         猪头的左偏移量
           * y:         猪头的上偏移量
           * show:      猪是否显示
           * timer:     猪移动的定时器
           * 
           */ 
          pigList: [
            { id: 1, dir: 'bottom',   position: [1, 0], x: 0, y: 0, show: true, timer: null },
            { id: 2, dir: 'bottom',   position: [1, 3], x: 0, y: 0, show: true, timer: null },
            { id: 3, dir: 'bottom',   position: [3, 5], x: 0, y: 0, show: true, timer: null },
            { id: 4, dir: 'bottom',   position: [5, 0], x: 0, y: 0, show: true, timer: null },
            { id: 5, dir: 'bottom',   position: [4, 8], x: 0, y: 0, show: true, timer: null },
            { id: 6, dir: 'bottom',   position: [7, 6], x: 0, y: 0, show: true, timer: null },
            { id: 7, dir: 'left',     position: [0, 4], x: 0, y: 0, show: true, timer: null },
            { id: 8, dir: 'left',     position: [1, 6], x: 0, y: 0, show: true, timer: null },
            { id: 9, dir: 'left',     position: [2, 7], x: 0, y: 0, show: true, timer: null },
            { id: 10, dir: 'left',    position: [2, 0], x: 0, y: 0, show: true, timer: null },
            { id: 11, dir: 'left',    position: [2, 2], x: 0, y: 0, show: true, timer: null },
            { id: 12, dir: 'left',    position: [3, 1], x: 0, y: 0, show: true, timer: null },
            { id: 13, dir: 'left',    position: [5, 3], x: 0, y: 0, show: true, timer: null },
            { id: 14, dir: 'left',    position: [5, 6], x: 0, y: 0, show: true, timer: null },
            { id: 15, dir: 'left',    position: [7, 1], x: 0, y: 0, show: true, timer: null },
            { id: 16, dir: 'left',    position: [7, 4], x: 0, y: 0, show: true, timer: null },
            { id: 17, dir: 'left',    position: [8, 3], x: 0, y: 0, show: true, timer: null },
            { id: 18, dir: 'right',   position: [6, 1], x: 0, y: 0, show: true, timer: null },
          ]
        }
      },
      mounted() {
        this.initMap()
        this.initPig()
        this.drawPig()
      },
      methods: {
        // 初始化地图
        initMap() {
          this.mapList = []
          for (let i = 0; i < this.row; i++) {
            this.mapList[i] = []
            for (let j = 0; j < this.row; j++) {
              this.mapList[i][j] = 0
            }
          }
          this.$forceUpdate()
        },

        // 初始化猪，获取猪的定位
        initPig() {
          this.pigList.forEach(item => {
            item.x = item.dir === 'right' ? this.cell * (item.position[1] - 1) : this.cell * item.position[1]
            item.y = item.dir === 'bottom' ? this.cell * (item.position[0] - 1) : this.cell * item.position[0]
          })
          this.$forceUpdate()
        },

        // 画猪 把猪的位置映射在地图上，用猪id标识，用于识别碰撞
        drawPig() {
          // 先把头映射在地图上
          this.pigList.forEach(item => {
            const [x, y] = item.position
            this.mapList[x][y] = item.id
          })
          // 再把尾巴映射在地图上
          const pigIdArr = this.pigList.map(item => item.id)
          this.mapList.forEach((tr, trIndex) => {
            tr.forEach((td, tdIndex) => {
              // 说明有猪头
              if (td !== 0 && pigIdArr.includes(td)) {
                const idIndex = pigIdArr.findIndex(item => item === td) // 找到猪
                const { dir, id } = this.pigList.find(item => item.id === td)
                if (dir === 'top') {
                  this.mapList[trIndex + 1][tdIndex] = id
                }
                if (dir === 'bottom') {
                  this.mapList[trIndex - 1][tdIndex] = id
                }
                if (dir === 'left') {
                  this.mapList[trIndex][tdIndex + 1] = id
                }
                if (dir === 'right') {
                  this.mapList[trIndex][tdIndex - 1] = id
                }
                // id用一次之后就删了，避免重复识别
                pigIdArr.splice(idIndex, 1)
              }
            })
          })
          this.$forceUpdate()
        },

        // 点击猪
        clickPig(pig) {
          const { dir, position, timer } = pig
          if (!timer && !this.isPigHeadKeepOff(pig)) {
            pig.timer = setInterval(() => {
              if (dir === 'top') {
                pig.y -= this.speed
              }
              if (dir === 'bottom') {
                pig.y += this.speed
              }
              if (dir === 'left') {
                pig.x -= this.speed
              }
              if (dir === 'right') {
                pig.x += this.speed
              }
              // 每次移动完，需要更新自身的position值
              this.updatePigPositon(pig)
            }, 10)
            // this.mapList[position[0]][position[1]] = 0
            // this.drawInitMap(pig)
            // if (dir === 'left') {
            //   pig.timer = setInterval(() => {
            //     if (this.handlePigMove(pig)) {
            //       clearInterval(pig.timer)
            //       pig.timer = null
            //       this.drawInitMap(pig)
            //       return
            //     }
            //     pig.x -= this.speed
            //     if (pig.x < -this.cell * 2) {
            //       clearInterval(pig.timer)
            //       pig.show = false
            //       pig.timer = null
            //       this.drawInitMap(pig)
            //     }
            //   }, 10)
            // }
            // if (dir === 'right') {
            //   pig.timer = setInterval(() => {
            //     if (this.handlePigMove(pig)) {
            //       clearInterval(pig.timer)
            //       pig.timer = null
            //       this.drawInitMap(pig)
            //       return
            //     }
            //     pig.x += this.speed
            //     if (pig.x > this.cell * this.col) {
            //       clearInterval(pig.timer)
            //       pig.show = false
            //       pig.timer = null
            //       this.drawInitMap(pig)
            //     }
            //   }, 10)
            // }
            // if (dir === 'top') {
            //   pig.timer = setInterval(() => {
            //     if (this.handlePigMove(pig)) {
            //       clearInterval(pig.timer)
            //       pig.timer = null
            //       this.drawInitMap(pig)
            //       return
            //     }
            //     pig.y -= this.speed
            //     if (pig.y < -window.innerWidth) {
            //       clearInterval(pig.timer)
            //       pig.show = false
            //       pig.timer = null
            //       this.drawInitMap(pig)
            //     }
            //   }, 10)
            // }
            // if (dir === 'bottom') {
            //   pig.timer = setInterval(() => {
            //     if (this.handlePigMove(pig)) {
            //       clearInterval(pig.timer)
            //       pig.timer = null
            //       this.drawInitMap(pig)
            //       return
            //     }
            //     pig.y += this.speed
            //     if (pig.y > window.innerWidth) {
            //       clearInterval(pig.timer)
            //       pig.show = false
            //       pig.timer = null
            //       this.drawInitMap(pig)
            //     }
            //   }, 10)
            // }
          }
        },

        // 判断猪头前面有没有其他动物 = true被挡住不能走
        isPigHeadKeepOff(pig) {
          const [x, y] = pig.position
          if (pig.dir === 'top') {
            return x - 1 >= 0 && this.mapList[x - 1][y] !== 0
          }
          if (pig.dir === 'bottom') {
            return x + 1 <= this.row && this.mapList[x + 1][y] !== 0
          }
          if (pig.dir === 'left') {
            return y - 1 >= 0 && this.mapList[x][y - 1] !== 0
          }
          if (pig.dir === 'right') {
            return y + 1 <= this.col && this.mapList[x][y + 1] !== 0
          }
          return false
        },

        // 每移动一次，就会判断自身的left和top值是否在整数格子中
        updatePigPositon(pig) {
          //
        },

        // 猪每次移动，都要计算它移动的位置，是否能被this.cell整除
        // 能整除 说明猪正好在某一个格子里
        // 不能整除，说明没完全到，或者已经超过一点了，这时候就要判断，如果超过一点的那个格子里有动物，则不能移动了
        // 注意：往下移动，往右移动，需要注意身体的宽度，不能直接用x或者y，（例如往下移动，虽然头在下面，则y的值是以距离顶部的值来计算的，所以需要y + 身体this.cell）
        // 注意：临界值
        handlePigMove(pig) {
          // 往上移动
          if (pig.dir === 'top') {
            const integer = pig.y / this.cell
            if (Number.isInteger(integer) && integer >= 0) {
              pig.position[0] = integer
            }
            if(pig.y < 0) {
              pig.position[0] = 0
            }
            if (integer >= 0 && Number.isInteger(integer) && integer - 1 >= 0) {
              return this.mapList[integer - 1][pig.position[1]] !== 0 && this.mapList[integer - 1][pig.position[1]] !== undefined
            }
          }
          // 往下移动
          if (pig.dir === 'bottom') {
            const integer = (pig.y + this.cell) / this.cell
            if (Number.isInteger(integer) && integer <= this.row) {
              pig.position[0] = integer
            }
            if (integer >= 0 && Number.isInteger(integer) && integer + 1 < this.row) {
              return this.mapList[integer + 1][pig.position[1]] !== 0 && this.mapList[integer + 1][pig.position[1]] !== undefined
            }
          }
          // 往左移动
          if (pig.dir === 'left') {
            const integer = pig.x / this.cell
            if (Number.isInteger(integer) && integer >= 0) {
              pig.position[1] = integer
            }
            if (integer >= 0 && Number.isInteger(integer) && integer - 1 >= 0) {
              return this.mapList[pig.position[0]][integer - 1] !== 0 && this.mapList[pig.position[0]][integer - 1] !== undefined
            }
          }
          // 往右移动
          if (pig.dir === 'right') {
            const integer = (pig.x + this.cell) / this.cell
            if (Number.isInteger(integer) && integer <= this.col) {
              pig.position[1] = integer
            }
            if (integer >= 0 && Number.isInteger(integer) && integer + 1 <= this.col) {
              return this.mapList[pig.position[0]][integer + 1] !== 0 && this.mapList[pig.position[0]][integer + 1] !== undefined
            }
          }
          return false
        },

        // 猪每次移动完成，暂停或者消失的时候，都要重新更新map里面，该猪对应的方块里面的id
        drawInitMap(pig) {
          // 先把猪之前的位置对应的map里面的id清掉
          this.mapList.forEach((item1, index1) => {
            item1.forEach((item2, index2) => {
              if (item2 === pig.id) {
                this.mapList[index1][index2] = 0
              }
            })
          })
          // 根据当前猪的x、y值，来计算它当前所在的position值，注意，猪消失就不用重新映射id了
          if (pig.show) {
            if (pig.dir === 'top' && Number.isInteger(pig.y / this.cell) && Number.isInteger(pig.x / this.cell)) {
              pig.position = [pig.y / this.cell, pig.x / this.cell]
            }
            if (pig.dir === 'bottom' && Number.isInteger(pig.y / this.cell + 1) && Number.isInteger(pig.x / this.cell)) {
              pig.position = [pig.y / this.cell + 1, pig.x / this.cell]
            }
            if (pig.dir === 'left' && Number.isInteger(pig.y / this.cell) && Number.isInteger(pig.x / this.cell)) {
              pig.position = [pig.y / this.cell, pig.x / this.cell]
            }
            if (pig.dir === 'right' && Number.isInteger(pig.y / this.cell) && Number.isInteger(pig.x / this.cell + 1)) {
              pig.position = [pig.y / this.cell, pig.x / this.cell + 1]
            }
            this.drawPig()
          }
        }
      }
    })
  </script>
</body>
</html>